#include "BaseNetworkChannel.h"
#include "Logger.h"
#include <algorithm>

namespace SeanNetwork {

BaseNetworkChannel::BaseNetworkChannel(asio::io_context& ioContext)
    : m_IoContext(ioContext),
      m_Strand(asio::make_strand(ioContext)),
      m_State(ConnectionState::Disconnected),
      m_Port(0),
      m_MessagePool(std::make_unique<MessagePool>()),
      m_ReconnectInitialDelay(1000),  // 1 second initial delay
      m_ReconnectMaxDelay(30000),     // 30 seconds max delay
      m_ReconnectMaxAttempts(5),      // Max 5 retry attempts
      m_ReconnectAttempts(0) {
    
    // Initialize network stats
    m_Stats.TotalBytesSent = 0;
    m_Stats.TotalBytesReceived = 0;
    m_Stats.MessagesSent = 0;
    m_Stats.MessagesReceived = 0;
    m_Stats.PacketLoss = 0;
    m_Stats.Retransmissions = 0;
    m_Stats.AverageRtt = 0;
    m_Stats.LatestRtt = 0;

    LOG_DEBUG("BaseNetworkChannel created");
}

BaseNetworkChannel::~BaseNetworkChannel() {
    Disconnect();
    
    std::unique_lock<std::shared_mutex> lock(m_CallbackMutex);
    m_MessageCallback = nullptr;
    m_ConnectionCallback = nullptr;

    LOG_DEBUG("BaseNetworkChannel destroyed");
}

bool BaseNetworkChannel::Initialize() {
    if (m_State != ConnectionState::Disconnected) {
        LOG_WARNING("初始化失败: 通道已连接或正在连接");
        return false;
    }
    
    LOG_DEBUG("初始化网络通道");
    m_MessagePool->Initialize();
    bool result = DoInitialize();
    
    if (result) {
        LOG_INFO("网络通道初始化成功");
    } else {
        LOG_ERROR("网络通道初始化失败");
    }
    
    return result;
}

bool BaseNetworkChannel::Connect(const std::string& host, uint16_t port) {
    if (m_State != ConnectionState::Disconnected) {
        LOG_WARNING("连接失败: 通道已连接或正在连接");
        return false;
    }
    
    if (host.empty() || port == 0) {
        LOG_ERROR("连接失败: 无效的主机或端口");
        return false;
    }
    
    m_Host = host;
    m_Port = port;
    m_ReconnectAttempts = 0;    
    
    LOG_INFO("正在连接到 " + host + ":" + std::to_string(port));
    return DoConnect(host, port);
}

void BaseNetworkChannel::Disconnect() {
    if (m_State == ConnectionState::Disconnected) {
        return;
    }
    
    LOG_INFO("正在断开连接");
    UpdateConnectionState(ConnectionState::Disconnected, "Disconnected by user");
    DoDisconnect();
    
    // Clear send queue
    {
        std::lock_guard<std::mutex> lock(m_SendQueueMutex);
        LOG_DEBUG("清空发送队列, 大小: " + std::to_string(m_SendQueue.size()));
        m_SendQueue.clear();
    }
}

bool BaseNetworkChannel::SendMsg(std::shared_ptr<NetworkMessage> message) {
    if (!message) {
        LOG_WARNING("发送失败: 消息为空");
        return false;
    }
    
    if (m_State != ConnectionState::Connected) {
        ConnectionState currentState = m_State.load();
        LOG_WARNING("发送失败: 通道未连接, 当前状态: " + ConnectionStateToString(currentState));
        return false;
    }
    
    // Update message timestamp before sending
    message->UpdateTimestamp();
    
    // Add to message pool for tracking
    if (m_MessagePool->AddMessage(message, GetChannelType())) {
        // 使用无锁队列保存消息
        m_MessagePool->EnqueueOutgoingMessage(message);
        
        // 根据消息优先级，也在原有队列中保存一份（用于优先级管理）
        {
            std::lock_guard<std::mutex> lock(m_SendQueueMutex);
            
            // Queue message based on priority
            auto priority = static_cast<MessagePriority>(message->GetHeader().Priority);
            
            if (priority == MessagePriority::Highest) {
                // Highest priority goes to the front of the queue
                m_SendQueue.push_front(message);
                LOG_DEBUG("添加最高优先级消息 ID:" + std::to_string(message->GetHeader().MessageId) + " 到发送队列前端");
            } else {
                // Other priorities go to the back
                m_SendQueue.push_back(message);
                LOG_DEBUG("添加消息 ID:" + std::to_string(message->GetHeader().MessageId) + 
                          " 优先级:" + std::to_string(static_cast<int>(priority)) + " 到发送队列");
            }
        }
        
        // Delegate to derived class implementation
        DoSendMessage(message);
        return true;
    }
    
    LOG_WARNING("消息未被添加到消息池, ID:" + std::to_string(message->GetHeader().MessageId));
    return false;
}

void BaseNetworkChannel::SetMessageCallback(MessageReceiveCallback callback) {
    std::unique_lock<std::shared_mutex> lock(m_CallbackMutex);
    m_MessageCallback = callback;
    LOG_DEBUG("消息回调已设置");
}

void BaseNetworkChannel::SetConnectionCallback(ConnectionStateCallback callback) {
    std::unique_lock<std::shared_mutex> lock(m_CallbackMutex);
    m_ConnectionCallback = callback;
    LOG_DEBUG("连接状态回调已设置");
}

ConnectionState BaseNetworkChannel::GetConnectionState() const {
    return m_State;
}

NetworkStats BaseNetworkChannel::GetNetworkStats() const {
    std::lock_guard<std::mutex> lock(m_StatsMutex);
    return m_Stats;
}

uint32_t BaseNetworkChannel::GetLatency() const {
    std::lock_guard<std::mutex> lock(m_StatsMutex);
    return m_Stats.LatestRtt;
}

void BaseNetworkChannel::Update() {
    // Check and clean up expired messages in the message pool
    m_MessagePool->Update();
    
    // Delegate to derived class for protocol-specific updates
    DoUpdate();
}

void BaseNetworkChannel::UpdateConnectionState(ConnectionState newState, const std::string& reason) {
    ConnectionState oldState = m_State.exchange(newState);
    
    if (oldState != newState) {
        // 记录连接状态变化
        LOG_INFO("连接状态变化: " + ConnectionStateToString(oldState) + " -> " + 
                ConnectionStateToString(newState) + ", 原因: " + reason);
        
        InvokeConnectionCallback(newState, reason);
    }
}

// 辅助方法：将连接状态转为字符串
std::string BaseNetworkChannel::ConnectionStateToString(ConnectionState state) {
    switch (state) {
        case ConnectionState::Disconnected: return "断开连接";
        case ConnectionState::Connecting: return "正在连接";
        case ConnectionState::Connected: return "已连接";
        case ConnectionState::Reconnecting: return "重新连接中";
        case ConnectionState::Failed: return "连接失败";
        default: return "未知状态";
    }
}

void BaseNetworkChannel::UpdateNetworkStats(uint64_t bytesSent, uint64_t bytesReceived, bool messageSent, bool messageReceived) {
    std::lock_guard<std::mutex> lock(m_StatsMutex);
    
    m_Stats.TotalBytesSent += bytesSent;
    m_Stats.TotalBytesReceived += bytesReceived;
    
    if (messageSent) {
        m_Stats.MessagesSent++;
    }
    
    if (messageReceived) {
        m_Stats.MessagesReceived++;
    }
    
    // 每隔100个消息记录一次网络统计信息
    if ((m_Stats.MessagesSent + m_Stats.MessagesReceived) % 100 == 0) {
        LOG_DEBUG("网络统计: 已发送=" + std::to_string(m_Stats.MessagesSent) + 
                 "条(" + std::to_string(m_Stats.TotalBytesSent) + "字节), " +
                 "已接收=" + std::to_string(m_Stats.MessagesReceived) + 
                 "条(" + std::to_string(m_Stats.TotalBytesReceived) + "字节), " +
                 "RTT=" + std::to_string(m_Stats.AverageRtt) + "ms");
    }
}

void BaseNetworkChannel::UpdateRtt(uint32_t rtt) {
    std::lock_guard<std::mutex> lock(m_StatsMutex);
    
    // Store latest RTT
    m_Stats.LatestRtt = rtt;
    
    // Add to samples (keeping last 10)
    m_RttSamples.push_back(rtt);
    if (m_RttSamples.size() > 10) {
        m_RttSamples.erase(m_RttSamples.begin());
    }
    
    // Calculate average RTT
    if (!m_RttSamples.empty()) {
        uint64_t sum = 0;
        for (auto sample : m_RttSamples) {
            sum += sample;
        }
        m_Stats.AverageRtt = static_cast<uint32_t>(sum / m_RttSamples.size());
    }
    
    // 记录显著的RTT变化
    static uint32_t lastLoggedRtt = 0;
    if (lastLoggedRtt == 0 || std::abs(static_cast<int>(lastLoggedRtt - m_Stats.AverageRtt)) > 20) {
        LOG_DEBUG("RTT更新: " + std::to_string(m_Stats.AverageRtt) + "ms");
        lastLoggedRtt = m_Stats.AverageRtt;
    }
}

uint32_t BaseNetworkChannel::CalculateReconnectDelay() const {
    // Exponential backoff with jitter
    uint32_t delay = m_ReconnectInitialDelay * (1 << std::min(m_ReconnectAttempts, 5u));
    delay = std::min(delay, m_ReconnectMaxDelay);
    
    // Add jitter (±10%)
    int jitter = static_cast<int>(delay * 0.1);
    delay += rand() % (2 * jitter) - jitter;
    
    LOG_DEBUG("计算重连延迟: " + std::to_string(delay) + "ms (尝试次数: " + 
              std::to_string(m_ReconnectAttempts) + ")");
    
    return delay;
}

void BaseNetworkChannel::HandleMessageAck(uint32_t messageId, bool success) {
    if (success) {
        // Message was delivered successfully
        m_MessagePool->AcknowledgeMessage(messageId, GetChannelType());
    } else {
        // Message failed to deliver, count as packet loss
        std::lock_guard<std::mutex> lock(m_StatsMutex);
        m_Stats.PacketLoss++;
        m_Stats.Retransmissions++;
    }
}

void BaseNetworkChannel::InvokeConnectionCallback(ConnectionState state, const std::string& reason) {
    std::shared_lock<std::shared_mutex> lock(m_CallbackMutex);
    if (m_ConnectionCallback) {
        try {
            // 在strand上调用回调以确保线程安全
            asio::post(m_Strand, [callback = m_ConnectionCallback, state, reason]() {
                try {
                    callback(state, reason);
                }
                catch (const std::exception& e) {
                    LOG_ERROR("连接回调执行异常: " + std::string(e.what()));
                }
            });
        }
        catch (const std::exception& e) {
            LOG_ERROR("连接回调投递异常: " + std::string(e.what()));
        }
    }
}

void BaseNetworkChannel::InvokeMessageCallback(std::shared_ptr<NetworkMessage> message) {
    std::shared_lock<std::shared_mutex> lock(m_CallbackMutex);
    if (m_MessageCallback && message) {
        try {
            // 在strand上调用回调以确保线程安全
            asio::post(m_Strand, [callback = m_MessageCallback, msg = message]() {
                try {
                    callback(msg);
                }
                catch (const std::exception& e) {
                    LOG_ERROR("消息回调执行异常: " + std::string(e.what()) + 
                             ", 消息ID: " + std::to_string(msg->GetHeader().MessageId));
                }
            });
        }
        catch (const std::exception& e) {
            LOG_ERROR("消息回调投递异常: " + std::string(e.what()) + 
                     ", 消息ID: " + std::to_string(message->GetHeader().MessageId));
        }
    }
}

} // namespace SeanNetwork 
